package com.laicunba.service.impl;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.UUID;

import net.sf.json.JSONArray;

import org.json.simple.JSONObject;
import org.springframework.stereotype.Service;

import com.laicunba.pojo.vo.WeiXinVO;
import com.laicunba.service.WeiXinService;
import com.laicunba.util.CacheUtil;
import com.laicunba.util.HttpUtil;
import com.laicunba.util.StringUtil;

@Service
public class WeiXinServiceImpl implements WeiXinService{

	@Override
	public WeiXinVO getWeiXinVO(WeiXinVO weiXinVO) throws Exception {
		if(StringUtil.isEmpty(weiXinVO.getLink())){
			weiXinVO.setErrInfo("地址为空");
			return weiXinVO;
		}
		if(StringUtil.isEmpty(weiXinVO.getAppid())){
			weiXinVO.setAppid("wxdedbeccf953c08dd");
		}
		if(StringUtil.isEmpty(weiXinVO.getSecret())){
			weiXinVO.setSecret("40c7de01cde7d8696ed689eedd67a43e");
		}

		weiXinVO.setNonceStr(create_nonce_str());
		weiXinVO.setTimestamp(create_timestamp());
		String string1;
		String jsapi_ticket = manageTicket(weiXinVO.getAppid(),weiXinVO.getSecret());
		weiXinVO.setJsapiTicket(jsapi_ticket);
		if(!jsapi_ticket.equals("error")&&jsapi_ticket!=null){
			// 注意这里参数名必须全部小写，且必须有序
			string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + weiXinVO.getNonceStr()
					+ "&timestamp=" + weiXinVO.getTimestamp() + "&url=" + weiXinVO.getLink();
			System.out.println(string1);

			try {
				MessageDigest crypt = MessageDigest.getInstance("SHA-1");
				crypt.reset();
				crypt.update(string1.getBytes("UTF-8"));
				weiXinVO.setSignature(byteToHex(crypt.digest()));
				weiXinVO.setErrInfo("ok!");
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}

		}else{
			weiXinVO.setErrInfo("jsapi_ticket is error or is null!");
		}
		return weiXinVO;
	}

	public String manageTicket(String appid,String secret) throws Exception{
		synchronized(this){
			String ticket = CacheUtil.getAttribute("ticket");	
			//System.out.println(ticket);
			if(ticket==null||ticket.equals("")){
				getTicket(appid,secret);
				ticket = CacheUtil.getAttribute("ticket");
				//System.out.println(ticket);
				return ticket;
			}else{
				return ticket;
			}
		}
	}
	
	private static void getTicket(String appid,String secret) throws Exception {
		JSONObject json = new JSONObject();
		String url1 = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
				+ appid + "&secret=" + secret;
		// 获得access_token 和expires_in
		String token = "[" + HttpUtil.doGet(url1) + "]";
		JSONArray jsonarray = JSONArray.fromObject(token);
		String accessToken = null;
		Integer expiresIn1 = 0;
		Integer expiresIn2 = 0;
		for (int i = 0; i < jsonarray.size(); i++) {
			net.sf.json.JSONObject job = jsonarray.getJSONObject(i);
			accessToken = (String) job.get("access_token");
			expiresIn1 = (Integer) job.get("expires_in");
		}
		if (accessToken != null || (!accessToken.equals(""))) {
			String url2 = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="
					+ accessToken + "&type=jsapi";
			// 获得tiket 和expires_in
			String jsapiTicket = "[" + HttpUtil.doGet(url2) + "]";
			jsonarray = JSONArray.fromObject(jsapiTicket);
			String ticket = null;
			for (int i = 0; i < jsonarray.size(); i++) {
				net.sf.json.JSONObject job = jsonarray.getJSONObject(i);
				ticket = (String) job.get("ticket");
				expiresIn2 = (Integer) job.get("expires_in");
			}
			if (ticket != null || (!ticket.equals(""))) {
				
				//处理最短缓存时间
				if (expiresIn2 > expiresIn1) {
					CacheUtil.setAttribute("ticket", ticket,expiresIn1-200);
				}else{
					CacheUtil.setAttribute("ticket", ticket,expiresIn2-200);
				}
			}
		} else {
			CacheUtil.setAttribute("ticket","error");
		}
	}

	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

	private static String create_nonce_str() {
		return UUID.randomUUID().toString();
	}

	private static String create_timestamp() {
		return Long.toString(System.currentTimeMillis() / 1000);
	}
}
